/*
 * FileUploadQueue.h
 *
 *  Created on: 2017年11月8日
 *      Author: zhengboyuan
 */

#ifndef FILEUPLOADQUEUE_H_
#define FILEUPLOADQUEUE_H_

#include "BasicType.h"
#include "StringArray.h"


/// 上传文件
class FileUpload
{
public:
	std::string	name;	/// 名称
	std::string	mime;	/// MIME类型
	std::string	filepath;	/// 文件路径

	bool check() const
	{
		return name.size() > 0 && filepath.size() > 0;
	}
};

typedef std::vector< FileUpload >	FileUploadArray;

/// 上传状态
enum UploadStatus
{
	kUploadBegin = 0,	/// 开始上传
	kUploadConnected,	/// 连接成功
	kUploadEnd,			/// 上传结束
	kUploadError		/// 上传错误
};

class FileUploadClient
{
public:
	class Sink
	{
	public:
		virtual ~Sink() {}

		/**
		 * 上传状态
		 * @param status	状态 @see UploadStatus
		 * @param result	成功时表示响应, 出错时表示原因描述
		 */
		virtual void onFileUploadStatus(FileUploadClient* client, int status, const std::string& result) =0;

		/**
		 * 上传进度
		 * @param total 总长度
		 * @param sent	发送字节数
		 */
		virtual void onFileUploadProgress(FileUploadClient* client, int total, int sent) =0;
	};

public:
	virtual ~FileUploadClient() {}

	virtual bool upload(const std::string& url, const StringMap& headers, const StringMap& formData, const FileUploadArray& files) =0;

	virtual void close() =0;

	virtual void cancel() =0;

	virtual void setSink(Sink* sink) =0;

	virtual const std::string& getUrl() =0;

	virtual int getId() =0;

	virtual void setId(int id) =0;

};



/// 上传文件任务
class FileUploadTask
{
public:
	int id;				/// 任务ID
	std::string url;	/// 上传URL
	StringMap headers;	/// 请求头
	StringMap formData;	/// 表单数据
	FileUploadArray files;	/// 文件

	FileUploadTask():
		id(),
		url(),
		formData(),
		files()
	{
	}
};

/**
 * 上传文件队列
 */
class FileUploadQueue
{
public:
	
	class Listener
	{
	public:
		virtual ~Listener() {}

		/**
		 * 上传状态
		 * @param tid 	任务ID
		 * @param task	任务
		 * @param status	状态 @see UploadStatus
		 * @param result	成功时表示响应, 出错时表示原因描述
		 */
		virtual void onFileUploadStatus(int tid, const FileUploadTask& task, int status, const std::string& result) =0;

		/**
		 * 上传进度
		 * @param tid	任务ID
		 * @param task	任务
		 * @param total 总长度
		 * @param sent	发送字节数
		 */
		virtual void onFileUploadProgress(int tid, const FileUploadTask& task, int total, int sent) =0;

	};

	static const int INVALID_ID = -1;

public:
	virtual ~FileUploadQueue() {}

	/// 开始
	virtual bool start() =0;

	/// 停止
	virtual void stop() =0;

	/**
	 * 添加文件上传任务
	 * @param tid		任务ID, <= 0 表示自动生成
	 * @param url		上传路径
	 * @param formData	表属性
	 * @param file		上传文件
	 * @return 任务ID, == -1 表示失败
	 */
	virtual int add(int tid, const std::string& url, const StringMap& header, const StringMap& formData, const FileUpload& file) =0;

	/**
	 * 添加多文件上传任务
	 * @param tid		任务ID, <= 0 表示自动生成
	 * @param url		上传路径
	 * @param formData	表属性
	 * @param files		上传文件
	 * @return 任务ID, == -1 表示失败
	 */
	virtual int addMulti(int tid, const std::string& url, const StringMap& header, const StringMap& formData, const FileUploadArray& files) =0;

	/**
	 * 取消上传任务
	 * @param tid	任务ID
	 */
	virtual void cancel(int tid) =0;

	/**
	 * 设置监听
	 * @param listener
	 */
	virtual void setListener(Listener* listener) =0;


};

#endif /* FILEUPLOADQUEUE_H_ */
